﻿using SimDev.Config;
using SimDev.ViewModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using WServer.ClientEngine;
using System.Linq;
using System.Security.Authentication;
using System.Windows.Threading;
using WServer.Service;
using System.Threading.Tasks;

namespace SimDev
{
    
    public class DTU : ViewModelBase
    {

        EasyClient _client = null;
        int _groupCount = 0;

        DateTime _lastActiveTime;

        const byte PROTOCOL_VERSION = 1;

        String sampleDataStr = "02 00 00 00 00 00 64 7F FF FF 7F FF FF 7F FF FF 80 00 00 80 00 00 7F FF FF 80 00 00 7F FF FF 80 00 00 80 00 00 7F FF FF 80 00 00 7F FF FF 7F FF FF 80 00 00 7F FF FF 00 02 13 00 0D 12 FF EE 55 FF FC A0 00 02 04 00 0D 5C FF EE 42 FF FC FC 00 02 1A 00 0D E6 FF EE 3E FF FC FE 00 02 43 00 0D C8 FF EE 07 FF FC B8 00 02 23 00 0D AA FF EE 24 FF FC E6 00 02 1F 00 0D 79 FF EE 7A FF FD 0C 00 02 50 00 0D 58 FF EE 6C FF FC E2 00 02 09 00 0C FF FF EE 41 FF FC D0 00 01 F2 00 0D 1B FF EE 3C FF FC 75 00 02 5A 00 0D 6E FF EE 54 FF FC 69 00 02 38 00 0D 6E FF EE 53 FF FC F4 00 02 64 00 0D B0 FF EE 75 FF FC E6 00 02 65 00 0D B1 FF EE 83 FF FC 91 00 02 02 00 0D C5 FF EE 83 FF FC CB 00 02 32 00 0D F2 FF EE 95 FF FC DB 00 02 76 00 0D B5 FF EE 8C FF FC CE 00 02 4B 00 0D 66 FF EE 74 FF FC EE 00 01 EB 00 0D 84 FF EE 5B FF FC D1 00 01 E8 00 0D 9F FF EE 51 FF FC BC 00 01 F5 00 0D C3 FF EE 4C FF FC E1 00 02 2E 00 0D F1 FF EE 09 FF FC E4 00 02 43 00 0D C3 FF ED CB FF FC BF 00 02 31 00 0D 9F FF EE 02 FF FC DC 00 02 16 00 0D CA FF EE 38 FF FC CA 00 02 41 00 0D 7E FF EE 72 FF FD 2C 00 02 6F 00 0D 66 FF EE 9A FF FC FC 00 02 35 00 0D 58 FF EE B2 FF FC E1 00 02 13 00 0D 94 FF EE BB FF FC C3 00 02 7C 00 0D D2 FF EE E7 FF FC 71 00 02 39 00 0D E8 FF EE D0 FF FC C2 00 01 ED 00 0E 09 FF EE D4 FF FC B6 00 01 FB 00 0E 53 FF EE B4 FF FC AC 00 02 0A 00 0E 3E FF EE 40 FF FC D2 00 02 3F 00 0D F9 FF EE 54 FF FC C6 00 02 44 00 0E 21 FF EE 63 FF FC C0 00 02 3F 00 0D D7 FF EE 4B FF FC 8D 00 02 16 00 0D DE FF EE 3F FF FC 62 00 01 F6 00 0D B4 FF EE 0A FF FC 56 00 01 F3 00 0D B4 FF EE 03 FF FC 8D 00 01 EB 00 0D CB FF EE 22 FF FC D3 00 02 37 00 0D A6 FF EE 22 FF FD 11 00 02 12 00 0D AA FF EE 15 FF FC D6 00 01 E3 00 0D DA FF EE 87 FF FC DC 00 01 E7 00 0E 05 FF EE 50 FF FC CD 00 02 0A 00 0E 30 FF ED D3 FF FC C0 00 02 26 00 0D AF FF EE 05 FF FC F5 00 02 0C 00 0D 43 FF EE 38 FF FD 01 00 02 03 00 0D 8D FF ED F6 FF FC EE 00 01 F0 00 0D B8 FF EE 36 FF FD 09 00 01 DD 00 0D D1 FF EE 51 FF FD 2B 00 01 D1 00 0D FC FF EE 3F FF FD 10 00 01 E4 00 0D FC FF EE 3F FF FD 11 00 01 EF 00 0D F5 FF EE 40 FF FD 2C 00 02 15 00 0D A1 FF EE 5A FF FD 16 00 02 2E 00 0D 7F FF EE 60 FF FC E6 00 02 15 00 0D 76 FF EE 47 FF FC CE 00 02 2E 00 0D 5C FF EE 3D FF FC E1 00 02 55 00 0D 82 FF EE 21 FF FC BD 00 02 21 00 0D D2 FF EE 0E FF FC A0 00 01 F2 00 0E 0D FF EE 4C FF FC A4 00 02 03 00 0D 92 FF EE 91 FF FC A0 00 02 3F 00 0D A0 FF EE 6D FF FC BE 00 02 1E 00 0D BE FF ED E2 FF FC ED 00 02 0B 00 0D AF FF ED CA FF FC D4 00 02 2D 00 0D EB FF EE 19 FF FC 9A 00 01 BF 00 0D 7E FF EE 20 FF FC 81 00 01 F7 00 0D 39 FF EE 1D FF FC 95 00 02 15 00 0D 79 FF EE 2A FF FC A0 00 01 F5 00 0D 8A FF EE 3D FF FC AD 00 02 02 00 0D 86 FF EE 34 FF FC C7 00 01 E3 00 0D 9C FF EE 71 FF FC 8B 00 02 0A 00 0D D5 FF EE 80 FF FC BD 00 02 04 00 0D A6 FF EE 3C FF FC DA 00 01 EA 00 0D 6C FF EE 3A FF FC 91 00 01 C3 00 0D 76 FF EE 49 FF FC 93 00 01 D9 00 0D 36 FF EE 66 FF FC F8 00 02 2E 00 0D 21 FF EE 94 FF FD 1F 00 02 50 00 0D 6C FF EE 44 FF FC F8 00 02 32 00 0D 3E FF EE 29 FF FC E9 00 02 16 00 0C C8 FF EE 7D FF FC EF 00 02 06 00 0D 69 FF EE 53 FF FC B2 00 01 C3 00 0D C5 FF EE 1C FF FC 54 00 01 C4 00 0D 74 FF EE 1F FF FC 12 00 01 D6 00 0D B9 FF EE 47 FF FC 51 00 01 AC 00 0E 04 FF EE 90 FF FC BD 00 02 17 00 0D E2 FF EE 9E FF FC CC 00 02 5D 00 0D B0 FF EE 96 FF FC AE 00 02 6B 00 0D 84 FF EE 51 FF FC B1 00 02 48 00 0D 37 FF EE 34 FF FC CD 00 02 42 00 0C D1 FF EE 24 FF FC BD 00 01 FD 00 0D 1C FF ED B7 FF FC BE 00 01 AD 00 0D 8B FF ED B3 FF FC DD 00 01 F0 00 0D D3 FF EE 1A FF FC E0 00 02 05 00 0D EB FF ED FB FF FC BB 00 01 EF 00 0D C4 FF ED D9 FF FC A3 00 02 13 00 0D B4 FF EE 06 FF FC BD FC BD 80";


        byte[] sampleDataStrBytes = null;
     
        byte[] _sendBuffer = new Byte[1024];

   
 
 
       
        public EasyClient Client
        {
            get { return _client; }
        }
       

        public DTU(int groupCount) {

            _groupCount = groupCount;
            var bytestrs = sampleDataStr.Split(new char[] {' '});

            sampleDataStrBytes = new byte[bytestrs.Length];

            for (int i = 0; i < bytestrs.Length; ++i)
            {
                sampleDataStrBytes[i] = Convert.ToByte(bytestrs[i], 16);   
            }
             

        }


     
 

        internal void DisConnect()
        {
            if (IsConnected)
                _client.Close();

            _client = null;
        }

        public bool IsConnected
        {
            get
            {
                if (_client == null)
                    return false;
                return _client.IsConnected;
            }
        }

        public void SendOnceData(string ip, int port) {

            if (IsConnected)
            {
                SendTestData();
            }
            else
            {
                Connect(ip, port);
            }
        }
        volatile Boolean autoSend = false;
        internal void AutoSendData(string ip, int port)
        {
            if (autoSend) return;
            autoSend = true;

            if (IsConnected)
            {

                SendTestDataForever();

            }
            else
            {
                Connect(ip, port);
            }
        }

        void SendTestDataForever() {

            Task.Run(() =>
            {
                
                while (autoSend)
                {
                    SendTestData();

                    Thread.Sleep(1);
                    
                }

             
            });
        }

        public void Connect(string ip, int port)
        {
            if (_client == null)
            {
                
                    _client = new EasyClient();

                _client.Connected += _client_Connected;
               
                _client.Closed += _client_Closed;

                _client.Error += _client_Error;

                _client.Initialize<DTUPackageInfo>(new DTUReceiveFilter(),PackageHandle);
            }
            _client.ConnectAsync(new IPEndPoint(IPAddress.Parse(ip), port));
           
             
        }

        private void _client_Error(object sender, ErrorEventArgs e)
        {
            Debug.WriteLine(e.Exception.Message);
            Debug.WriteLine(e.Exception.StackTrace);
        }

        int _ReceivedBytes = 0;
        public int ReceivedBytes
        {
            get
            {
                return _ReceivedBytes;
            }
            set
            {
                _ReceivedBytes = value;
                RaisePropertyChanged("ReceivedBytes");
            }
        }

        int _SendBytes = 0;
        public int SendBytes
        {
            get
            {
                return _SendBytes;
            }
            set
            {
                _SendBytes = value;
                RaisePropertyChanged("SendBytes");
            }
        }

        int _RequestCount = 0;
        public int RequestCount
        {
            get
            {
                return _RequestCount;
            }
            set
            {
                _RequestCount = value;
                RaisePropertyChanged("RequestCount");
            }
        }

        int _HandledRequestCount = 0;
        public int HandledRequestCount
        {
            get
            {
                
                return _HandledRequestCount;
            }
            set
            {
                _HandledRequestCount = value;
                RaisePropertyChanged("HandledRequestCount");
            }
        }



        private void _client_Closed(object sender, EventArgs e)
        {
             
            RaisePropertyChanged("IsConnected");
        }
        public class RequestByte
        {
            public int Index { get; set; }

            public ushort Value { get; set; }


            public string HexValue { get { return Value.ToString("X2"); } }

            public bool IsHead
            {
                get
                {
                    return Index < 4;
                }
            }
        }

        ObservableCollection<RequestByte> _RequestBytes=new ObservableCollection<RequestByte>();
        public ObservableCollection<RequestByte> RequestBytes
        {
            get { return _RequestBytes; }
           
        }

        string _requestTime;
        public string RequestTime
        {
            get { return _requestTime; }
            private set
            {
                _requestTime = value;
                RaisePropertyChanged("RequestTime");
            }
        }
      

        void PackageHandle(DTUPackageInfo package)
        {
            _lastActiveTime = DateTime.Now;
            RequestCount++;
            this.Dispatcher.Invoke(() => {
                _RequestBytes.Clear();
                int i = 0;
                Array.ForEach(package.Header, d => _RequestBytes.Add(new RequestByte() { Index = i++, Value = d }));
                Array.ForEach(package.Body, d => _RequestBytes.Add(new RequestByte() { Index = i++, Value = d }));
                RequestTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
            });


     

        }

        private void _client_Connected(object sender, EventArgs e)
        {

            RaisePropertyChanged("IsConnected");
         
            _lastActiveTime = DateTime.Now;
            _client.NoDelay = true;
            //连接成功后开始发送数据
            if (autoSend)
            {
                SendTestDataForever();
            }
            else
            {
                SendTestData();
            }
           
        }

        private void SendTestData() {
            Task.Run(() =>
            {
                for (int i = 0; i < _groupCount; ++i)
                    _client.Send(sampleDataStrBytes);
            });
        }

        public void Stop()
        {
            autoSend = false;
        }


        public class MessageHead
        {
            public byte Version;     //一个字节

            public byte MsgType;//一个字节
            public ushort BodyLength;  //两个字节

            public byte Type
            {
                get
                {
                    return MsgType;

                }
            }
        }//共20个字节 

        public bool enableheart = true;


    
        byte _SerialNumber=0;



        public void SendDataToDTU(string dstimei, byte[] data)
        {
          
            _sendBuffer.Initialize();
            byte[] dstImeiBytes = ASCIIEncoding.ASCII.GetBytes(dstimei);
            
            //头 + imei + 序号 + 数据
            int len = dstImeiBytes.Length + 1 + data.Length;
            _sendBuffer[0] = PROTOCOL_VERSION;
            _sendBuffer[1] = MessageType.SRCDTU_SERVER;
            _sendBuffer[2] = (byte)(len >> 8);
            _sendBuffer[3] = (byte)len;
            Buffer.BlockCopy(dstImeiBytes, 0, _sendBuffer, 4, 15);
            _sendBuffer[19] = _SerialNumber++;
            Buffer.BlockCopy(data, 0, _sendBuffer, 20, data.Length);         



            _client.Send(new ArraySegment<byte>(_sendBuffer, 0, len+4));
          
        }

        public void SendReportToServer(byte reportType, byte[] data)
        {

            _sendBuffer.Initialize();
                     
            int len =  data.Length;
            _sendBuffer[0] = PROTOCOL_VERSION;
            _sendBuffer[1] = reportType;
            _sendBuffer[2] = (byte)(len >> 8);
            _sendBuffer[3] = (byte)len; 
            Buffer.BlockCopy(data, 0, _sendBuffer, 4, data.Length); 

            _client.Send(new ArraySegment<byte>(_sendBuffer, 0, len + 4));

        }





    }
}
